<?php
/*
 * 递归去除多余转义符
 */
function dostripslashes( $value ) {
    $value = is_array( $value ) ? array_map( 'dostripslashes', $value ) : stripslashes( $value );
    return $value;
}


/**
 * import  载入包含文件
 *
 * @param filename    需要载入的文件名或者文件路径
 * @param auto_error    自动提示扩展类载入出错信息
 */
function import( $sfilename, $auto_error = FALSE ) {
    if ( isset( $GLOBALS[ "import_file" ][ md5( $sfilename ) ] ) ) return TRUE; // 已包含载入，返回
    // 检查$sfilename是否直接可读
    if ( TRUE == @is_readable( $sfilename ) ) {
        require( $sfilename ); // 载入文件
        $GLOBALS[ 'import_file' ][ md5( $sfilename ) ] = TRUE; // 对该文件进行标识为已载入
        return TRUE;
    }

    $include_path = array( APP_PATH . '/system/core/', APP_PATH . '/system/lib/' );
    foreach ( $include_path as $sp_include_path ) {
        // 检查当前搜索路径中，该文件是否已经载入
        if ( isset( $GLOBALS[ "import_file" ][ md5( $sp_include_path . $sfilename ) ] ) ) return TRUE;
        if ( is_readable( $sp_include_path . $sfilename ) ) {
            require( $sp_include_path . $sfilename ); // 载入文件
            $GLOBALS[ 'import_file' ][ md5( $sp_include_path . $sfilename ) ] = TRUE; // 对该文件进行标识为已载入
            return TRUE;
        }
    }
    if ( TRUE == $auto_error ) Error( "未能找到名为：{$sfilename}的文件" );
    return FALSE;
}

/**
 * C  类实例化函数  自动载入类定义文件，实例化并返回对象句柄
 *
 * @param class_name    类名称
 * @param args   类初始化时使用的参数，数组形式
 * @param sdir 载入类定义文件的路径，可以是目录+文件名的方式，也可以单独是目录。sdir的值将传入import()进行载入
 * @param force_inst 是否强制重新实例化对象
 */
function C( $class_name, $args = null, $sdir = null, $force_inst = FALSE ) {
    // 检查类名称是否正确，以保证类定义文件载入的安全性
    if ( preg_match( '/[^a-z0-9\-_.]/i', $class_name ) ) Error( $class_name . "类名称错误，请检查。" );
    // 检查是否该类已经实例化，直接返回已实例对象，避免再次实例化
    if ( TRUE != $force_inst ) if ( isset( $GLOBALS[ "inst_class" ][ $class_name ] ) ) return $GLOBALS[ "inst_class" ][ $class_name ];
    // 如果$sdir不能读取，则测试是否仅路径
    if ( null != $sdir && !import( $sdir ) && !import( $sdir . '/' . $class_name . '.php' ) ) return FALSE;

    $has_define = FALSE;
    // 检查类定义是否存在
    if ( class_exists( $class_name, false ) || interface_exists( $class_name, false ) ) {
        $has_define = TRUE;
    } else {
        if ( TRUE == import( $class_name . '.php' ) ) {
            $has_define = TRUE;
        }
    }
    if ( FALSE != $has_define ) {
        $argString = '';
        $comma = '';
        if ( null != $args ) for ( $i = 0; $i < count( $args ); $i++ ) {
            $argString .= $comma . "\$args[$i]";
            $comma = ', ';
        }
        eval( "\$GLOBALS['inst_class'][\$class_name]= new \$class_name($argString);" );
        return $GLOBALS[ "inst_class" ][ $class_name ];
    }
    Error( $class_name . "类定义不存在，请检查。" );
}

/**
 * Error 框架定义的系统级错误提示
 *
 * @param msg    出错信息
 * @param stop    是否停止程序
 */
function Error( $msg, $stop = TRUE ) {
    $traces = debug_backtrace();
    $bufferabove = ob_get_clean();
    require_once APP_PATH . "/system/core/Error.php";
    if ( TRUE == $stop ) exit;
}

/*
 * 获取应用程序请求变量值，同时也可以指定获取的变量所属。
 *
 * @param $name       获取的变量名称，如果为空，则返回全部的请求变量
 * @param $default    当前获取的变量不存在的时候，将返回的默认值
 */
function R( $name, $deault = 0 ) {
    if ( $name == null ) {
        return $_REQUEST;
    }
    if ( isset( $_REQUEST[ $name ] ) ) {
        return $_REQUEST[ $name ];
    }
    if ( $deault ) {
        $_REQUEST[ $name ] = $deault;
        return $deault;
    }
    return false;
}

/**
 * S    获取请求信息
 * @param $a    请求参数
 */
function S( $a = 'domain' ) {
    if ( $a == 'domain' ) {
        $http = ( isset( $_SERVER[ 'HTTPS' ] ) && $_SERVER[ 'HTTPS' ] != 'off' ) ? 'https://' : 'http://';
        return "{$http}{$_SERVER[ 'HTTP_HOST' ]}";
    }
    if ( $a == 'ip' ) {
        if ( isset( $_SERVER[ 'HTTP_CLIENT_IP' ] ) ) {
            $ip = $_SERVER[ 'HTTP_CLIENT_IP' ];
        } elseif ( isset( $_SERVER[ 'REMOTE_ADDR' ] ) ) {
            $ip = $_SERVER[ 'REMOTE_ADDR' ];
        }
        return $ip;
    }
    if ( isset( $_SERVER[ $a ] ) ) {
        return $_SERVER[ $a ];
    }
    return false;
}

/**
 * md6  数据加密
 * @param $str         要加密的字符串
 * @param $key         加密密匙
 * @param $method      加密方法
 */
function md6( $str = '', $method = 'md5', $key = null ) {
    if ( $key == null && defined( 'APP_KEY' ) ) $key = APP_KEY;
    $obj = C( "Encrypt" );
    $method = "_" . $method;
    return $obj->$method( $str, $key );
}

/*
 * 返回目录指定类型所有文件
 *
 * @param $dir           文件目录
 * @param $fileType      文件类型
 */
function list_file( $dir, $fileType = "php" ) {
    $lists = glob( $dir . "*.{$fileType}" );
    return $lists;
}

/*
 * 返回目录下所有目录
 *
 * @param $dir       文件目录
 */
function list_dir( $dir ) {
    $lists = glob( $dir );
    foreach ( $lists as $k => $list ) {
        if ( !is_dir( $list ) ) {
            unset( $lists[ $k ] );
        } else {
            $lists[ $k ] = basename( $list );
        }
    }
    return $lists;
}

/**
 * rm               递遍历删除目录和目录下所有文件
 * @param $dir     目录路径
 * @param $flag     是否删除目录
 */
function rm( $dir, $flag = true ) {
    if ( !is_dir( $dir ) ) {
        return false;
    }
    $handle = opendir( $dir );
    while ( ( $file = readdir( $handle ) ) !== false ) {
        if ( $file != "." && $file != ".." ) {
            is_dir( "$dir/$file" ) ? rm( "$dir/$file" ) : @unlink( "$dir/$file" );
        }
    }
    if ( readdir( $handle ) == false && $flag == true ) {
        closedir( $handle );
        @rmdir( $dir );
    }
}

/**
 * mkdirs           循环建立目录
 * @param $dir      目录路径
 */
function mkdirs( $dir ) {
    if ( !is_dir( $dir ) ) {
        mkdirs( dirname( $dir ) );
        umask( 0 );
        return @mkdir( $dir, 0777 );
    }
    return true;
}

/*
 * is_writable_dir    检查目录是否可写
 * @param $dir        要检查目录路径
 */
function is_writable_dir( $dir ) {
    if ( !is_dir( $dir ) ) {
        @mkdir( $dir, 0777 );
    }
    if ( is_dir( $dir ) ) {
        if ( $fp = @fopen( "$dir/test.txt", 'w' ) ) {
            @fclose( $fp );
            @unlink( "$dir/test.txt" );
            return true;
        }
    }
    return false;
}

/**
 * formatFileSize        格式化文件大小
 * @param $fileSize     原文件大小
 * @param $len          小数点后的位数
 */
function formatFileSize( $fileSize, $len = 2 ) {
    switch ( true ) {
        case $fileSize >= 1073741824 :
            return round( $fileSize / 1073741824, $len ) . 'GB';
        case $fileSize >= 1048576 :
            return round( $fileSize / 1048576, $len ) . 'MB';
        case $fileSize >= 1024 :
            return round( $fileSize / 1024, $len ) . 'KB';
        default :
            return $fileSize . '字节';
    }
    return $fileSize;
}

/**
 * formatDate     个性化时间
 * @param $date     要被个性化的时间戳
 */
function formatDate( $date ) {
    if ( !$date ) return '-';
    $sec = time() - $date;
    switch ( true ) {
        case $sec < 60:
            return $sec . '秒前';
        case $sec < 3600:
            return round( $sec / 60 ) . '分钟前';
        case $sec < 86400:
            return round( $sec / 3600 ) . '小时前';
        case $sec < ( 86400 * 7 ):
            return round( $sec / 86400 ) . '天前';
        case $sec < ( 86400 * 7 * 4 ):
            return round( $sec / ( 86400 * 7 ) ) . '周前';
        default:
            return date( "Y年n月d日", $date );
    }
}

/**
 * substring 字符串截取，支持中文和其他编码
 * @param $str     需要截取的字符串
 * @param $start   开始位置
 * @param $length  截取长度
 * @param $charset 编码格式
 * @param $suffix  截断字符串后缀
 */
function substring( $str, $length, $start = 0, $suffix = "", $charset = "utf-8" ) {
    if ( function_exists( "mb_substr" ) ) {
        return mb_substr( $str, $start, $length, $charset ) . $suffix;
    } elseif ( function_exists( 'iconv_substr' ) ) {
        return iconv_substr( $str, $start, $length, $charset ) . $suffix;
    }
    $re[ 'utf-8' ] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re[ 'gb2312' ] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re[ 'gbk' ] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re[ 'big5' ] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    preg_match_all( $re[ $charset ], $str, $match );
    $slice = join( "", array_slice( $match[ 0 ], $start, $length ) );
    return $slice . $suffix;
}

/**
 * arraySortByKey       对二维数组按指定key排序
 * @param $arr          要排序的数组
 * @param $key          需要排序的key
 * @param $asc          升序or降序
 */
function arraySortByKey( $array, $key, $asc = true ) {
    $result = array();
    // 整理出准备排序的数组
    foreach ( $array as $k => $v ) {
        $values[ $k ] = isset( $v[ $key ] ) ? $v[ $key ] : '';
    }
    unset( $v );
    // 对需要排序键值进行排序
    $asc ? asort( $values ) : arsort( $values );
    // 重新排列原有数组
    foreach ( $values as $k => $v ) {
        $result[ $k ] = $array[ $k ];
    }
    return $result;
}

/**
 * htmlText        从html中提取文本信息
 *
 * @param $data   要截取的内容
 * @param $len    截取的长度,0 则截取全部
 * @param $html   清除HTML代码
 */
function htmlText( $data, $len = 0, $html = false ) {
    //if ( $html ) $data = strip_tags( $data );
    if ( $html ) $data = preg_replace( "/<[^>]+>/i", "", $data );
    $data = str_replace( array( "\n", "\t", "\r" ), "", $data );
    if ( $len ) $data = substring( $data, $len );
    return $data;
}

/*
 *  Thumb               生成图片缩略图 (宽和高都不=0时等比缩放有效, 否则按照宽高进行缩放)
 *  @param $src_file    要生成缩略图文件
 *  @param $rel_type    返回缩略图方式 0:绝对物理路径, 1: URL绝对路径
 *  @param $thumbwidth  要生成缩略图宽度
 *  @param $thumbheight 要生成缩略图高度
 */
function Thumb( $src_file, $thumbwidth = 220, $thumbheight = 0, $rel_type = 1 ) {

    $src_file = ltrim( $src_file, "\/\\" );
    // 原图绝对路径
    $source = APP_PATH . "/{$src_file}";

    // 原图不存在或不可读则退出
    if ( !is_readable( $source ) ) return $src_file;

    // 获取原图像宽高
    $result = getimagesize( $source );
    $imagewidth = $result[ 0 ];
    $imageheight = $result[ 1 ];

    // 如果来源图像小于或等于缩略图则返回源图像作为缩略图,免去操作
    if ( $imagewidth <= $thumbwidth && $thumbheight <= $thumbheight ) {
        return ( $rel_type == 1 ? $GLOBALS[ 'setting' ][ 'weburl' ] : '' ) . "/{$src_file}";
    }

    // 缩略图绝对路径
    $fileParts = pathinfo( $source );
    $thumb_path = "{$fileParts[ 'dirname' ]}/{$fileParts[ 'filename' ]}_{$thumbwidth}_{$thumbheight}.{$fileParts[ 'extension' ]}";

    // 缩略图相对路径
    $thumb_file = ltrim( str_replace( APP_PATH, "", $thumb_path ), "\/\\" );

    // 如果缩略图存在则按$rel_type返回
    if ( @is_readable( $thumb_file ) ) {
        return ( $rel_type == 1 ? $GLOBALS[ 'setting' ][ 'weburl' ] : APP_PATH ) . "/{$thumb_file}";
    }

    $type = strtolower( $fileParts[ 'extension' ] ) == 'bmp' ? 'jpg' : strtolower( $fileParts[ 'extension' ] );
    $type == 'jpg' && $type = 'jpeg';

    if ( $thumbwidth && !$thumbheight ) { //有宽无高
        $thumb[ 'width' ] = $thumbwidth;
        $thumb[ 'height' ] = $imageheight * ( $thumbwidth / $imagewidth );
    } else if ( !$thumbwidth && $thumbheight ) { //有高无宽
        $thumb[ 'width' ] = $imagewidth * ( $thumbheight / $imageheight );
        $thumb[ 'height' ] = $thumbheight;
    } else { // 计算缩放比例
        $scale = min( $thumbwidth / $imagewidth, $thumbheight / $imageheight );
        if ( $scale >= 1 ) { // 超过原图大小不再缩略
            $thumb[ 'height' ] = $imageheight;
            $thumb[ 'width' ] = $imagewidth;
        } else { // 缩略图尺寸
            $thumb[ 'height' ] = (int)( $imageheight * $scale );
            $thumb[ 'width' ] = (int)( $imagewidth * $scale );
        }
    }

    // 载入原图
    $createFun = "ImageCreateFrom{$type}";
    $src_img = $createFun( $source );

    // 创建缩略图
    if ( $type != 'gif' && function_exists( 'imagecreatetruecolor' ) ) {
        $thumb_img = imagecreatetruecolor( $thumb[ 'width' ], $thumb[ 'height' ] );
    } else {
        $thumb_img = imagecreate( $thumb[ 'width' ], $thumb[ 'height' ] );
    }

    // 复制图片
    if ( function_exists( 'imagecopyresampled' ) ) {
        @ImageCopyResampled( $thumb_img, $src_img, 0, 0, 0, 0, $thumb[ 'width' ], $thumb[ 'height' ], $imagewidth, $imageheight );
    } else {
        @ImageCopyResized( $thumb_img, $src_img, 0, 0, 0, 0, $thumb[ 'width' ], $thumb[ 'height' ], $imagewidth, $imageheight );
    }

    //生成缩略图
    $outfunc = "image{$type}";
    if ( $type == 'jpeg' ) { // 对jpeg图形设置隔行扫描与图片质量
        imageinterlace( $thumb_img, 1 );
        $outfunc( $thumb_img, $thumb_path, 95 );
    } else {
        $outfunc( $thumb_img, $thumb_path );
    }

    //销毁临时图像
    @ImageDestroy( $src_img );
    @ImageDestroy( $thumb_img );

    // 返回缩略图
    return ( $rel_type == 1 ? $GLOBALS[ 'setting' ][ 'weburl' ] : APP_PATH ) . "/{$thumb_file}";
}